﻿using Microsoft.EntityFrameworkCore.Diagnostics;
using System;
using System.Data.Common;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Currency.Infra.EntityFramework.Interceptor
{
    /// <summary>
    /// 拦截器
    /// </summary>
    public class DefaultDbCommandInterceptor : DbCommandInterceptor
    {
        private readonly Stopwatch _stopwatch = new Stopwatch();

        /// <summary>
        /// 读取开始拦截
        /// </summary>
        /// <param name="command"></param>
        /// <param name="eventData"></param>
        /// <param name="result"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override ValueTask<InterceptionResult<DbDataReader>> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result, CancellationToken cancellationToken = default(CancellationToken))
        {
            _stopwatch.Restart();
            return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
        }

        /// <summary>
        /// 读取结束拦截拦截
        /// </summary>
        /// <param name="command"></param>
        /// <param name="eventData"></param>
        /// <param name="result"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override ValueTask<DbDataReader> ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default(CancellationToken))
        {
            _stopwatch.Stop();
            Trace.TraceInformation($"\r\n执行时间:{_stopwatch.ElapsedMilliseconds} 毫秒\r\n-->ScalarExecuted.Command:{command.CommandText}\r\n");
            var parameters = new StringBuilder();
            foreach (DbParameter param in command.Parameters)
            {
                parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);
            }
            Trace.TraceInformation($"\r\n参数:{parameters}");
            return base.ReaderExecutedAsync(command, eventData, result, cancellationToken);
        }

        /// <summary>
        /// 查询开始拦截
        /// </summary>
        /// <param name="command"></param>
        /// <param name="eventData"></param>
        /// <param name="result"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override ValueTask<InterceptionResult<int>> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default(CancellationToken))
        {
            _stopwatch.Restart();
            return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken);
        }

        /// <summary>
        /// 查询结束拦截
        /// </summary>
        /// <param name="command"></param>
        /// <param name="eventData"></param>
        /// <param name="result"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public override ValueTask<int> NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default(CancellationToken))
        {
            _stopwatch.Stop();
            Trace.TraceInformation($"\r\n执行时间:{_stopwatch.ElapsedMilliseconds} 毫秒\r\n-->ScalarExecuted.Command:{command.CommandText}\r\n");
            var parameters = new StringBuilder();
            foreach (DbParameter param in command.Parameters)
            {
                parameters.AppendLine(param.ParameterName + " " + param.DbType + " = " + param.Value);
            }
            Trace.TraceInformation($"\r\n参数:{parameters}");
            return base.NonQueryExecutedAsync(command, eventData, result, cancellationToken);
        }
    }
}
